var crypto = require('crypto');

var utils = (() => {
	var encode_base64 = raw => {
		var s = new Buffer(raw).toString('base64');
		var npad = 0;
        while (s.endsWith('=')) {
            npad++;
            s = s.substr(0, s.length - 1);
        }
		return s + npad;
	};
	var decode_base64 = x => {
		var npad = parseInt(x.substr(x.length - 1));
        x = x.substr(0, x.length - 1) + "=".repeat(npad);
		var s = new Buffer(x, 'base64').toString('utf-8');
		return s;
	};
	var hmac_md5 = (data, key) => {
		return crypto.createHmac('md5', key).update(data).digest('hex');
	};
	var hmac = data => {
		return hmac_md5(data, 'rsms');
	};
	var make_token = (seq, role) => {
		var raw_token = JSON.stringify({ seq, role });
		var raw_token64 = encode_base64(raw_token);
		var auth = hmac(raw_token64);
        var auth64 = encode_base64(auth);
        return raw_token64 + "." + auth64;
	};
	var check_token = token => {
		var shards = token.split('.');
        if (shards.length !== 2) throw 'denied';
        var auth = hmac(shards[0]);
        var auth64 = encode_base64(auth);
        if (auth64 !== shards[1]) throw 'denied';
        return shards[0];
	};
	var unpack_token = token => {
		var raw_token64 = check_token(token);
        var raw_token = decode_base64(raw_token64);
		return JSON.parse(raw_token);
	};
	return {
		make_token, unpack_token
	}
})();

module.exports = utils;
